package com.blgroup.oa.web.controller;


import com.blgroup.oa.domain.vo.*;
import com.blgroup.oa.service.ProcessService;
import org.activiti.engine.identity.User;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * 用户Controller
 *
 * @author tangyulong
 * @version v1.0
 * @ClassName: UserController
 * @date 2018年5月16日 下午11:35:41
 */
@RestController
@RequestMapping(value = "/process")
public class ProcessController extends BaseController {

    @Autowired
    ProcessService processService;

    /**
     * 开始请假流程
     *
     * @param dto
     * @param bindingResult
     * @param model
     * @param request
     * @return
     */
    @PostMapping(value = "/startVacation")
    public ModelAndView startVacation(@Valid @ModelAttribute("dto") VacationForm dto, BindingResult bindingResult, Model model, HttpServletRequest request) {
        try {
            ProcessInstance pi = this.processService.startVacation(dto);
            model.addAttribute("processInstance", pi);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listProcessInstance(dto.getUserId(), "vacation", model, request);
    }

    /**
     * 流程实例列表
     *
     * @param userId
     * @param processType
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/list")
    public ModelAndView listProcessInstance(String userId, String processType, Model model, HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("processing");
        List<ProcessVO> list = null;
        if (StringUtils.isBlank(userId)) {
            userId = request.getSession().getAttribute("userId").toString();
        }
        try {
            if ("expense".equals(processType)) {
                list = this.processService.listExpenseAccount(userId);
            } else if ("salary".equals(processType)) {
                list = this.processService.listSalaryAdjust(userId);
            } else {
                processType = "vacation";
                list = this.processService.listVacation(userId);
            }
            model.addAttribute("list", list);
            model.addAttribute("processType", processType);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return mv;
    }

    /**
     * 开始报销流程
     *
     * @param dto
     * @param user
     * @param processType
     * @param model
     * @param request
     * @return
     */
    @PostMapping(value = "/startExpenseAccount")
    public ModelAndView startExpenseAccount(@Valid @ModelAttribute("dto") ExpenseAccountForm dto, User user, String processType, Model model, HttpServletRequest request) {
        try {
            ProcessInstance processInstance = processService.startExpenseAccount(dto);
            model.addAttribute("processInstance", processInstance);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listProcessInstance(dto.getUserId(), "expense", model, request);
    }

    /**
     * 开始调整薪资流程
     *
     * @param dto
     * @param processType
     * @param model
     * @param request
     * @return
     */
    @PostMapping(value = "/startSalaryAdjust")
    public ModelAndView startSalaryAdjust(@Valid @ModelAttribute("dto") SalaryForm dto, String processType, Model model, HttpServletRequest request) {
        try {
            ProcessInstance processInstance = processService.startSalaryAdjust(dto);
            model.addAttribute("processInstance", processInstance);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listProcessInstance(dto.getUserId(), "salary", model, request);
    }

    /**
     * 任务列表
     *
     * @param userId
     * @param taskType
     * @param request
     * @return
     */
    @RequestMapping(value = "/listTask", method = RequestMethod.GET)
    public ModelAndView listTask(String userId, String taskType, Model model, HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("task");
        List<TaskVO> list = null;
        if (StringUtils.isBlank(userId)) {
            userId = request.getSession().getAttribute("userId").toString();
        }
        try {
            if ("assignee".equals(taskType)) {
                list = this.processService.listAssigneeTasks(userId);
            } else {
                taskType = "candidate";
                list = this.processService.listTasks(userId);
            }
            model.addAttribute("tasks", list);
            model.addAttribute("taskType", taskType);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return mv;
    }

    /**
     * ·
     * 声明获取任务
     *
     * @param taskId
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/claim", method = RequestMethod.GET)
    public ModelAndView claim(String userId, String taskId, Model model, HttpServletRequest request) {
        try {
            this.processService.claim(taskId, userId);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listTask(userId, "claim", model, request);
    }

    /**
     * 任务进行操作
     *
     * @param taskId
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/perform", method = RequestMethod.GET)
    public ModelAndView claim(String taskId, Model model, HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("auditTask");
        try {
            List<CommentVO> comments = processService.getComments(taskId);
            List<FormField> formFields = processService.getFormFields(taskId);
            model.addAttribute("comments", comments);
            model.addAttribute("formFields", formFields);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return mv;
    }

    /**
     * 完成任务
     *
     * @param userId
     * @param content
     * @param taskId
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/complete", method = RequestMethod.GET)
    public ModelAndView complete(String userId, String content, String taskId, Model model, HttpServletRequest request) {
        try {
            this.processService.complete(taskId, content, userId);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listTask(userId, "assignee", model, request);
    }

    /**
     * 取消操作
     *
     * @param userId
     * @param content
     * @param taskId
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/cancelAdjust", method = RequestMethod.GET)
    public ModelAndView cancelAdjust(String userId, String content, String taskId, Model model, HttpServletRequest request) {
        try {
            this.processService.cancelAdjust(taskId, content, userId);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return listTask(userId, "assignee", model, request);
    }


    /**
     * 跳转流程图
     *
     * @param model
     * @param request
     * @return
     */
    @GetMapping(value = "/diagram")
    public ModelAndView diagram(String processInstanceId, Model model, HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("diagram");
        model.addAttribute("processInstanceId", processInstanceId);
        return mv;
    }

    // 显示流程图
    @GetMapping(value = "/showDiagram")
    public String showDiagram(String processInstanceId, HttpServletResponse response) {
        OutputStream out = null;
        try {
            InputStream is = this.processService.getDiagram(processInstanceId);
            response.setContentType("multipart/form-data;charset=utf8");
            out = response.getOutputStream();
            out.write(getImgByte(is));
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (Exception e) {
            }
        }
        return null;
    }

    /*
        将输入流转换为byte数组
     */
    private byte[] getImgByte(InputStream is) throws IOException {
        ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
        int b;
        while ((b = is.read()) != -1) {
            bytestream.write(b);
        }
        byte[] bs = bytestream.toByteArray();
        bytestream.close();
        return bs;
    }

}
